package client;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;



public class BackgroundSound {
	
	private final String midiFolder="./data/suoni/";
	private final String midiFolderWin=".\\\\data\\\\suoni\\\\midi\\\\";
	private String midi= midiFolder + "JurassicPark.mid";
	private Sequencer sequencer;
	
	public void inizializzatore(){
		try{
			start(midi);
		} catch (MidiUnavailableException e){
			System.err.println("Errore, periferica midi non disponibile");
		} catch (IOException e){
			System.err.println("Errore, lettura: " + midi);
		} catch (InvalidMidiDataException e){
			System.err.println("Errore, midi non valido: " + midi);
		}
	}
	
	public BackgroundSound(){
		inizializzatore();
	}
	
	public BackgroundSound(String midiFileName){
		midi=midiFolder + midiFileName;
		inizializzatore();
	}
	
	public ArrayList<String> getMidiAvaible(){
		ArrayList<String> nomeFiles = new ArrayList<String>();
		File folder=new File(midiFolder);
		if (folder!=null){
			File[] listaMidi=folder.listFiles();
			for (File file : listaMidi) {
				nomeFiles.add(file.toString());
			}
		}
		return nomeFiles;
	}
	
	public ArrayList<String> getMidiAvaibleOnlyName(){
		ArrayList<String> nomeFiles = getMidiAvaible();
		int i=0;
		for (String midi : nomeFiles) {
			nomeFiles.set(i, midi.replaceAll(this.midiFolder, "").replaceAll(this.midiFolderWin, ""));
			i++;
		}
		return nomeFiles;
	}
	
	public void start(String filename)
	throws MidiUnavailableException, InvalidMidiDataException, IOException
	{
		final Synthesizer synthesizer;
		
	
		String	strFilename = filename;
		File	midiFile = new File(strFilename);
	
		/* We read in the MIDI file to a Sequence object.  This object
		 * is set at the Sequencer later.
		 */
		Sequence sequence = MidiSystem.getSequence(midiFile);
	
		/* Now, we need a Sequencer to play the sequence.  Here, we
		 * simply request the default sequencer without an implicitly
		 * connected synthesizer
		 */
		sequencer = MidiSystem.getSequencer(false);
	
		/* The Sequencer is still a dead object.  We have to open() it
		 * to become live.  This is necessary to allocate some
		 * ressources in the native part.
		 */
		sequencer.open();
	
		/* Next step is to tell the Sequencer which Sequence it has to
		 * play. In this case, we set it as the Sequence object
		 * created above.
		 */
		sequencer.setSequence(sequence);
	
		/* We try to get the default synthesizer, open() it and chain
		 * it to the sequencer with a Transmitter-Receiver pair.
		 */
		synthesizer = MidiSystem.getSynthesizer();
		synthesizer.open();
		Receiver	synthReceiver = synthesizer.getReceiver();
		Transmitter	seqTransmitter = sequencer.getTransmitter();
		seqTransmitter.setReceiver(synthReceiver);
	
		/* To free system resources, it is recommended to close the
		 * synthesizer and sequencer properly.
		 *
		 * To accomplish this, we register a Listener to the
		 * Sequencer. It is called when there are "meta" events. Meta
		 * event 47 is end of track.
		 *
		 * Thanks to Espen Riskedal for finding this trick.
		 */
		sequencer.addMetaEventListener(new MetaEventListener()
			{
				public void meta(MetaMessage event)
				{
					if (event.getType() == 47)
					{
						sequencer.close();
						if (synthesizer != null)
						{
							synthesizer.close();
						}
					}
				}
			});
	
		/* Here, we set the loop points to loop over the whole
		 * sequence. Setting the loop end point to -1 means using the
		 * last tick of the sequence as end point of the loop.
		 *
		 * Furthermore, we set the number of loops to loop infinitely.
		 */
		sequencer.setLoopStartPoint(0);
		sequencer.setLoopEndPoint(-1);
		sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
	
		/* 
		 * Now, we can start over.
		 */
		sequencer.start();
	}
	
	public void stop(){
		sequencer.stop();
	}
	
	public static String getTitle(String filename){
		String[] splittedString=filename.split("/");
		if (splittedString.length<=1) {
			System.out.println("Sei su windows hai le barre al contrario!!!");
			splittedString=filename.split("[\\\\]");
		}
		String title=splittedString[splittedString.length-1];
		return title.replaceAll(".mid", "");
	}
	
	public void newSong(String NomeMidi){
		this.midi=this.midiFolder+NomeMidi;
		
		stop();
		inizializzatore();
	}
}
